package com.ly.ocw.service.weixin;

import java.util.Date;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springside.modules.mapper.JsonMapper;

import com.ly.ocw.comm.DateUtil;
import com.ly.ocw.entity.weixin.WeixinAccessToken;
import com.ly.ocw.entity.weixin.WeixinAccessTokenLog;
import com.ly.ocw.entity.weixin.WeixinPublic;
import com.ly.ocw.exception.ServerException;
import com.ly.ocw.repository.weixin.WeixinAccessTokenDao;
import com.ly.ocw.repository.weixin.WeixinAccessTokenLogDao;
import com.ly.ocw.rest.dto.ReceiveAccessTokenDto;
import com.ly.ocw.utils.HttpUtil;

/**
 * 
 * 
 * @author Peter
 */
// Spring Service Bean的标识.
@Component
public class WeixinAccessTokenService {

	private static JsonMapper mapper = JsonMapper.nonDefaultMapper();

	private static Logger logger = LoggerFactory.getLogger(WeixinAccessTokenService.class);

	@Autowired
	private WeixinConf weixinConf;

	@Autowired
	private WeixinPublicService weixinPublicService;

	@Autowired
	private WeixinAccessTokenDao weixinAccessTokenDao;

	@Autowired
	private WeixinAccessTokenLogDao weixinAccessTokenLogDao;

	public String getAccessToken() throws ServerException {
		WeixinAccessToken weixinAccessToken = weixinAccessTokenDao.getByWeixinPublicId(weixinConf.getPublicId());
		if (weixinAccessToken == null) {
			// 数据库中没有AccessToken信息，从微信服务器获取AccessToken
			logger.info("a数据库中没有AccessToken信息，从微信服务器获取AccessToken");
			ReceiveAccessTokenDto dto = receiveAccessToken();
			weixinAccessToken = dtoToEntity(dto);
			WeixinAccessTokenLog log = dtoToEntityLog(dto);
			
			weixinAccessTokenDao.save(weixinAccessToken);
			weixinAccessTokenLogDao.save(log);
			
		} else {
			// 判断是否过期
			if (DateUtil.isExpires(weixinAccessToken.getUpdateDate(),weixinAccessToken.getExpiresIn().intValue())){
				logger.info("access_token过期：  "+DateUtil.sdf_1.format(weixinAccessToken.getUpdateDate()));
				//过期，重新获取access_token
				Long id = weixinAccessToken.getId();
				ReceiveAccessTokenDto dto = receiveAccessToken();
				weixinAccessToken = dtoToEntity(dto);
				weixinAccessToken.setId(id);
				WeixinAccessTokenLog log = dtoToEntityLog(dto);
				weixinAccessTokenDao.update(weixinAccessToken);
				weixinAccessTokenLogDao.save(log);
				
			}

		}
		return weixinAccessToken.getAccessToken();
	}

	// 获取access_token
	public ReceiveAccessTokenDto receiveAccessToken() throws ServerException {
		WeixinPublic weixinPublic = weixinPublicService.getCatchWeixinPublic();
		String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + weixinPublic.getAppId() + "&secret=" + weixinPublic.getAppSecret();

		String body = HttpUtil.httpGet(url);
		ReceiveAccessTokenDto bean = mapper.fromJson(body, ReceiveAccessTokenDto.class);

		if (StringUtils.isNotBlank(bean.getErrcode())) {
			throw new ServerException(bean.getErrcode(), bean.getErrmsg());
		}

		return bean;
	}

	private WeixinAccessToken dtoToEntity(ReceiveAccessTokenDto dto) {
		WeixinAccessToken token = new WeixinAccessToken();
		token.setAccessToken(dto.getAccess_token());
		token.setCreateDate(new Date());
		token.setExpiresIn(Long.parseLong(dto.getExpires_in()));
		token.setUpdateDate(new Date());
		token.setWeixinPublicId(weixinConf.getPublicId());
		return token;
	}

	private WeixinAccessTokenLog dtoToEntityLog(ReceiveAccessTokenDto dto) {
		WeixinAccessTokenLog tokenLog = new WeixinAccessTokenLog();

		if (StringUtils.isBlank(dto.getErrcode())) {
			tokenLog.setAccessToken(dto.getAccess_token());
			tokenLog.setExpiresIn(Long.parseLong(dto.getExpires_in()));
		} else {
			tokenLog.setErrcode(dto.getErrcode());
			tokenLog.setErrmsg(dto.getErrmsg());
		}

		tokenLog.setCreateDate(new Date());
		tokenLog.setWeixinPublicId(weixinConf.getPublicId());
		return tokenLog;
	}

}
